package Lock;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.CloseableUtils;

import java.util.concurrent.*;

/**
 * @author create on 2021/7/12
 * 客户端调用zk分布式锁的例子
 * 启动五个线程，每个线程
 */
public class LockingExample {
    private static final int QTY = 5;
    private static final int REPETITION = QTY * 10;
    private static final String CONNECTION_STRING = "127.0.0.1:2181";
    private static final String PATH = "/examples/locks";

    public static void main(String[] args) {
        //共享资源
        final FakeLimitResource resource = new FakeLimitResource();
        ExecutorService service = Executors.newFixedThreadPool(QTY);
        try {
            for (int i = 0; i <QTY ; i++) {
                final int index = i;
                Callable<Void> task = new Callable<Void>() {
                    public Void call() throws Exception {
                        CuratorFramework client = CuratorFrameworkFactory.newClient(CONNECTION_STRING,  new ExponentialBackoffRetry(1000, 3,Integer.MAX_VALUE));
                        try{
                            client.start();
                            ExampleClientThatLocks lock = new ExampleClientThatLocks(client, PATH, resource, "Client :" + index);
                            for (int j = 0; j <REPETITION ; j++) {
                                lock.doWork(1, TimeUnit.SECONDS);
                            }
                        }catch (InterruptedException e){
                            Thread.currentThread().interrupt();
                        }catch (Exception e){
                            e.printStackTrace();
                        }finally {
                            CloseableUtils.closeQuietly(client);
                        }
                        return null;
                    }
                };
                service.submit(task);
            }
            service.shutdown();
            service.awaitTermination(10, TimeUnit.MINUTES);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}
